package main

import (
	"fmt"
	slices "hh/geekbang/util/slice"
	"math/rand/v2"
)

func DeleteTest() {
	s := []int{1, 2, 3, 4, 5}
	s, _, err := Delete(len(s), s)
	if err != nil {
		fmt.Printf("error test: %v \n", err)
	}
	s, _, err = Delete(-1, s)
	if err != nil {
		fmt.Printf("error test: %v \n", err)
	}
	s, _, _ = Delete(0, s)
	fmt.Printf("delete test： %v, %v == [2, 3, 4, 5]\n", slices.Equals(s, []int{2, 3, 4, 5}), s)
	s, _, _ = Delete(len(s)-1, s)
	fmt.Printf("delete test： %v, %v == [2, 3, 4]\n", slices.Equals(s, []int{2, 3, 4}), s)
	s, _, _ = Delete(1, s)
	fmt.Printf("delete test： %v, %v == [2, 4]\n", slices.Equals(s, []int{2, 4}), s)

	fmt.Println("test : -------- calculate capacity ---------")
	_, isShrink := CalcShrinkCap(30, 60)
	fmt.Printf("test : %v \n", isShrink == false)
	// 256
	newCap, isShrink := CalcShrinkCap(100, 200)
	fmt.Printf("test : %v\n", !isShrink && newCap == 200)
	newCap, isShrink = CalcShrinkCap(100, 255)
	fmt.Printf("test : %v\n", isShrink && newCap == 200)
	// others
	newCap, isShrink = CalcShrinkCap(1000, 1500)
	fmt.Printf("test : %v\n", !isShrink && newCap == 1500)
	newCap, isShrink = CalcShrinkCap(1000, 1510)
	fmt.Printf("test : %v %v\n", isShrink && newCap == 1250, newCap)

	fmt.Println("----------testShrink-------------")
	s = make([]int, 1000)

	for i, length := 0, len(s); i < length; i++ {
		s, _, _ = DeleteWithoutShrink(len(s)-1, s)
		s = probShrink(s)
	}

	fmt.Println("----------random deletion test------")
	s = make([]int, 1000)
	for i, length := 0, len(s); i < length; i++ {
		s, _, _ = Delete(rand.IntN(len(s)), s)
	}
	fmt.Printf("s: %v, len: %d, cap: %d\n", s, len(s), cap(s))
	fmt.Println("over")
}

func probShrink[T any](slice []T) []T {
	length, capacity := len(slice), cap(slice)
	newCap, isShrink := CalcShrinkCap(length, capacity)
	if !isShrink {
		return slice
	}
	fmt.Printf("len: %d, oldCap: %d, newCap: %d, factor: %.2f\n", length, capacity, newCap, float64(newCap)/float64(length))
	newSlice := make([]T, length, newCap)
	copy(newSlice, slice)
	return newSlice
}
